#include "xinfomatlayoutmanager.h"
#include <xinfomatremoteproxy.h>   //define enterMenuMode exitMenuMode
#include <qtextstream.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qtimer.h>
#include "xhtmlplayer.h"
#include "xmovieplayer.h"

XInfomatLayoutManager::XInfomatLayoutManager(QObject* parent ) :QObject(parent),  /*{{{*/
	m_playIndex(0), m_pluIndex(0), m_currentPlu(0), m_isPlayingPlu(false), 
	m_isTempPassPluValid(false),m_isPassPluValid(false),
	m_isPlayersValid(false), m_needSwitchPartial(false)
{ 
	m_layout = m_xbootConf.getLayout();
	m_xHtmlPlayer = new XHtmlPlayer();   assert (NULL!=m_xHtmlPlayer);
	m_xMoviePlayer = new XMoviePlayer(); assert (NULL!=m_xMoviePlayer);
	connect (&m_tmCheckPlayers, SIGNAL(timeout()), this, SLOT(onCheckPlayers()));
	m_tmCheckPlayers.stop();
	setScreenMode(EPartialScreen); 
} /*}}}*/

XInfomatLayoutManager::~XInfomatLayoutManager()
{  /* {{{ */
	if(NULL!=m_xHtmlPlayer) {
		delete m_xHtmlPlayer;
		m_xHtmlPlayer = NULL;
	}
	if(NULL!=m_xMoviePlayer) {
		delete m_xMoviePlayer;
		m_xMoviePlayer = NULL;
	}
} /* }}} */

/* *****************************************************************
 *                      PUBLIC FUNCTION                
 * *****************************************************************/
int XInfomatLayoutManager::doHalt()   //TODO: CHNAGE NAME AS stop... Make a stop shared function /* {{{ */
{
	LOG_T("Stop Html And Movie Player");
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	}else {
		LOG_E("Error.StopHtmlPlayer");
		return -1;
	};
	m_xHtmlPlayer->hide();
	clearRoutinePlayConnections();
	clearPluPlayConnections();
	disconnect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_xMoviePlayer->stopPlay();
	m_isCPlayerIdle = false;
	return 0;
} /* }}} */

int XInfomatLayoutManager::doQueue()  /* {{{ */
{
	LOG_T("Do Queue,Stop Html and Movie Player");
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	}else {
		LOG_E("Error.StopHtmlPlayer");
		return -1;
	};
	m_xHtmlPlayer->hide();
	clearRoutinePlayConnections();
	clearPluPlayConnections();
	connect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));   //Avoid corrputed scrren.
	m_xMoviePlayer->stopPlay();
	m_isCPlayerIdle = false;
	m_event = EQueue;
	m_isPlayingPlu = false;  //reset plu
	m_currentPlu = -1;       //reset plu
	m_tmCheckPlayers.start(100);
	return 0;
} /* }}} */

int XInfomatLayoutManager::doResume()  /* {{{ */
{
	LOG_T("Do Resume");
	m_xHtmlPlayer->show();
	if (m_layout != k_layout_7 || m_layout !=k_layout_10) {  // Queue Only
		doRoutine();
	}
	return 0;
} /* }}} */

int XInfomatLayoutManager::doEnterMenuMode() /* {{{ */
{
//	LOG_T("Do EnterMenuMode");
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	};
	m_isCPlayerIdle = false;
	clearRoutinePlayConnections();  //necessary
	connect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_xMoviePlayer->stopPlay();
	m_event = EEnterMenuMode;
	m_tmCheckPlayers.start(100);   //onCheckPlayers();
	return 0;
} /* }}} */

int XInfomatLayoutManager::doExitMenuMode() /* {{{ */
{
	LOG_T("Do ExitMenuMode");
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	};
	m_isCPlayerIdle = false;
	connect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_xMoviePlayer->stopPlay();
	
	m_event = EExitMenuMode;
	m_tmCheckPlayers.start(100);   //onCheckPlayers();
	return 0;
} /* }}} */

int XInfomatLayoutManager::doEnterScreenSaver() /*{{{*/
{
	LOG_T("Do EnterScreenSaver");
	doEnterMenuMode();
	return 0;
} /* }}} */

int XInfomatLayoutManager::doExitScreenSaver() /* {{{ */
{
	LOG_T("Do exitScreenSaver");
	doExitMenuMode();
	return 0;
} /* }}} */

int XInfomatLayoutManager::doRoutine(const bool needSwitchPartial)  /* [+] */ /* {{{ */
{
	LOG_T("Do Routine");
	updatePlayList();
	assert (m_playlist.size() !=0);
	m_isTempPassPluValid = false;  //reset plu
	m_event = ERoutine;  
	m_needSwitchPartial = needSwitchPartial;
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	};
	m_isCPlayerIdle = false;
	connect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_xMoviePlayer->stopPlay();
	m_tmCheckPlayers.start(100);   //onCheckPlayers();
	return 0;
} /* }}} */

/* *****************************************************************
 * 						PROTECTED 
 * *****************************************************************/
int XInfomatLayoutManager::stopPlayersAndHide() /* {{{ */
{
//	LOG_T("stopPlayersAndHide()");
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	}else {
		LOG_E("Error.StopHtmlPlayer");
		return -1;
	};
	m_xHtmlPlayer->hide();
	disconnect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_xMoviePlayer->stopPlay();
	m_isCPlayerIdle = true;
	return 0;
} /* }}} */

void XInfomatLayoutManager::startRoutinePlay()    /* {{{ */
{
	clearRoutinePlayConnections();
	clearPluPlayConnections();
	connect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayRoutineDone(int)));
	emit sgUpdateList(EUpdateRoutineList);
} /* }}} */

void XInfomatLayoutManager::clearRoutinePlayConnections() /* {{{ */
{
	disconnect(m_xHtmlPlayer,SIGNAL(sgPlayHtmlDone(int)), this, SLOT(onPlayRoutineDone(int)));
	disconnect(m_xMoviePlayer, SIGNAL(sgPlayMovieDone(int)), this, SLOT(onPlayRoutineDone(int)));
	disconnect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayRoutineDone(int)));
} /* }}} */

void XInfomatLayoutManager::onPlayRoutineDone(int id)   /* [-slot] */  /* {{{ */
{
	LOG_T("[ROUTINE LIST] UPDATE NEW FILE");
	LOG_T("Received Index: %02d", id);
	LOG_T("Current  Index: %02d", m_playIndex-1);
	if (id==EUpdateRoutineList) {
		LOG_T("[OK]: sgUpdateRoutineList");
		disconnect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayRoutineDone(int)));
	}
	else if (id != m_playIndex-1)  {
		LOG_E("[Reject] Id is wrong, Correct Id: %02d", m_playIndex-1);
		return;
	}else {
		LOG_T("[OK] Update New File");
	}

	updatePlayList();
	if (m_playIndex >= m_playlist.size()) { 
		LOG_T("[Reset] Reach Max Value:m_playIndex %d", m_playIndex );
		m_playIndex = 0;
	}
	clearRoutinePlayConnections();
	clearPluPlayConnections();
	bool isExist = isFileExist(m_playlist[m_playIndex].file.toStdString().c_str());
	if (isExist) {  
		switch (m_playlist[m_playIndex].type)
		{   // m_playIndex : Id
		case EHtml:
			LOG_T("Waiting ... signal ... html timer: m_playIndex:%02d", m_playIndex);
			connect (m_xHtmlPlayer, SIGNAL(sgPlayHtmlDone(int)), this, SLOT(onPlayRoutineDone(int)));
			m_xHtmlPlayer->playHtml(m_playlist[m_playIndex].file.toStdString().c_str(), m_playlist[m_playIndex].timeout, m_playIndex);   //TODO: TOO MANY PARAMETERS
			m_xHtmlPlayer->show();  //For k_layout_6
			m_xHtmlPlayer->raise(); // For k_layout_6
			break;
		case EPicture:
			LOG_T("Waiting ... signal ... Picture Timer :m_playIndex:%02d", m_playIndex);
			connect (m_xMoviePlayer,SIGNAL(sgPlayMovieDone(int)), this, SLOT(onPlayRoutineDone(int)));
			m_xMoviePlayer->playMovie(m_playlist[m_playIndex].file.toStdString().c_str(), m_playlist[m_playIndex].timeout, m_playIndex); //TODO: TOO MANY PARAMETERS
			break;
		case EVideo:
			LOG_T("Waiting ... signal ... Video PlayEnd : m_playIndex:%02d", m_playIndex);
			connect (m_xMoviePlayer,SIGNAL(sgPlayMovieDone(int)), this, SLOT(onPlayRoutineDone(int)));
			m_xMoviePlayer->playMovie(m_playlist[m_playIndex].file.toStdString().c_str(), m_playIndex);   //TODO: TOO Many Parameters
			m_isCPlayerIdle = false;  //Add --> Queue Crash
			break;
		default:
			LOG_E("[Error] Unkown File");
			return;
		}
		m_playIndex++;
	} else {
		LOG_E("[Error]: Normally it should not be here.File not exist");
		connect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayRoutineDone(int)));
		m_playIndex++;
		emit sgUpdateList(EUpdateRoutineList);
		return;
	}
	return;
} /* }}} */

/* *****************************************************************
 *  			 Processing Plu Play Functions   
 * *****************************************************************/
int XInfomatLayoutManager::doPlu(const int pluNo, const bool needSwitchPartial)  /* {{{ */
{
	LOG_T(" PROCESSING PLU: %02d", pluNo);
	m_isTempPassPluValid = false;   	// Clear last value
	if (0!=isPluValid(pluNo)) {
		LOG_E("[Error] PLU File Invalid");
		return -1;
	}
	LOG_T(" Temp PLU File Vaild. ");
	m_isTempPassPluValid = true;
	m_isPassPluValid = true;
	m_plulist.clear();
	m_plulist = m_tempPluList;
	m_currentPlu = pluNo;
	m_pluIndex = 0;
	//stop html
	if (0==m_xHtmlPlayer->stopPlay()) {
		m_isHtmlIdle = true;
	};
	//stop cplayer  [waiting for signal here]
	m_isCPlayerIdle = false;    // suppose
	connect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_xMoviePlayer->stopPlay(); //stop it if cplayer is running
	m_needSwitchPartial = needSwitchPartial;

	if (m_event == EQueue) {
		m_needSwitchPartial = true;
	}
	//both of the players must be stopped and then call event processing.
	m_tmCheckPlayers.start(100); 
	return 0;
} /* }}} */

int XInfomatLayoutManager::isPluValid(const int pluNo)   /* [#] */ /* {{{ */
{
	if (0!=buildPluList(pluNo)) {
		LOG_E("Error.PLU.List");
		return -1;
	}
	if (m_isPlayingPlu) {    
		if(pluNo == m_currentPlu) { 
			LOG_T("Return:Same PLU");
			return(-1);       
		} 
	}
	return 0;
} /* }}} */

void XInfomatLayoutManager::clearPluPlayConnections()  /*  [#] */ /* {{{ */
{
	disconnect (m_xHtmlPlayer, SIGNAL(sgPlayHtmlDone(int)), this, SLOT(onPlayPlu(int)));
	disconnect (m_xMoviePlayer,SIGNAL(sgPlayMovieDone(int)), this, SLOT(onPlayPlu(int)));
	disconnect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayPlu(int)));
} /* }}} */

void XInfomatLayoutManager::onPlayPlu(int id)   /* {{{ */
{
	m_isTempPassPluValid = false;
	m_isPassPluValid = false;
	if (id == EUpdatePluList) {  //Update directly 
		disconnect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayPlu(int)));
	}

	if (id == m_plulist.size()-1) {
		LOG_T("==============================");
		LOG_T(" [FINISH] [PLU] PLAY OVER");
		LOG_T("==============================");
		m_isPlayingPlu = false;
		clearPluPlayConnections();
		doRoutine();
		return;
	}
	m_isPlayingPlu = true;   // Avoid Playing Same PLU
	m_currentPlu = m_plulist[m_pluIndex].serial;
	//  LOG_T("m_currentPlu:%02d",m_currentPlu);
	//	LOG_T("m_pluIndex:%02d",m_pluIndex);
	//  LOG_T("PLU:%s, index:%02d,timeout:%02d", m_plulist[m_pluIndex].file.toStdString().c_str(),m_pluIndex, m_plulist[m_pluIndex].timeout);
	switch (m_plulist[m_pluIndex].type)
	{
	case EHtml:
		connect (m_xHtmlPlayer, SIGNAL(sgPlayHtmlDone(int)), this, SLOT(onPlayPlu(int)));
		m_xHtmlPlayer->playHtml(m_plulist[m_pluIndex].file.toStdString().c_str(), m_plulist[m_pluIndex].timeout, m_pluIndex);
		break;
	case EPicture:
		connect (m_xMoviePlayer, SIGNAL(sgPlayMovieDone(int)), this, SLOT(onPlayPlu(int)));
		m_xMoviePlayer->playMovie(m_plulist[m_pluIndex].file.toStdString().c_str(), m_plulist[m_pluIndex].timeout, m_pluIndex);
		break;
	case EVideo:
		connect (m_xMoviePlayer, SIGNAL(sgPlayMovieDone(int)), this, SLOT(onPlayPlu(int)));
		m_xMoviePlayer->playMovie(m_plulist[m_pluIndex].file.toStdString().c_str(), m_pluIndex);
		break;
	default:
		LOG_E("[Error] : No Such File Type");
		return;
	}
	m_pluIndex++;
	LOG_T("============= Waiting for Signal =====================\n ");
} /* }}} */

void XInfomatLayoutManager::startPluPlay() /* {{{ */
{
	clearPluPlayConnections();
	clearRoutinePlayConnections();
	connect (this, SIGNAL(sgUpdateList(int)), this, SLOT(onPlayPlu(int)));
	emit sgUpdateList(EUpdatePluList);
} /* }}} */

void XInfomatLayoutManager::processInfomatEvents()  /* {{{ */
{
	LOG_T("Process Infomat Events :%02d", m_event);
	switch (m_event) 
	{
	case ERoutine:
		LOG_T("[Event:Routine] Start");
		if (m_needSwitchPartial) {
			LOG_T("[ScreenSwitch To Partial]");
			m_needSwitchPartial=false;
			setScreenMode(EPartialScreen);
		}
		startRoutinePlay();
		break;
	case EPlu:
		// Handle with continus & quick PLU request
		if (m_isPlayersValid && m_isPlayersValid) {
			LOG_T("[Event:Plu] Start");
			if (EScreenModeOn == m_xbootConf.screenMode()) {
				LOG_T("Set Partial Screen");
				setScreenMode(EPartialScreen);  //Exception: Fast Press PLU# twice
//				m_needSwitchPartial = false;
			}
			startPluPlay();
			return;
		} else {
			LOG_T("[Return][DoNothing]");
		}
	case EEnterMenuMode:
	case EEnterScreenSaver:
		LOG_T("[Event]  EnterMenuMode/EnterScreenSaver");
		if (m_isPlayersValid) {
			//reset plu
			m_isPlayingPlu = false;
			m_currentPlu = -1;
			setScreenMode(EFullScreen);
			doRoutine(); //Do Full Screen
		}
		break;
	case EExitMenuMode:
	case EExitScreenSaver:
		LOG_T("[Event] ExitMenuMode/ExitScreenSaver");
		m_isPlayingPlu = false;
		m_currentPlu = -1;
		if (m_isPlayersValid) {
			setScreenMode(EPartialScreen);
			doRoutine();
			if (m_layout == k_layout_6) 
				emit sgQueueWidgetRepaint();  
			if (m_layout == k_layout_8 || m_layout == k_layout_9 || m_layout == k_layout_10) 
				emit sgWMRepaint();
		}
		break;
	case EQueue:
		LOG_T("Event Process Queue");
		if (m_isPlayersValid) {
			if (m_layout == k_layout_6)    //Remove:onfict with showQueue()
				emit sgQueueWidgetRepaint();
			if (m_layout == k_layout_8 || m_layout == k_layout_9 || m_layout == k_layout_10) 
				emit sgWMRepaint();
		}
		return;
	}
} /* }}} */

int XInfomatLayoutManager::buildPluList(const int plu)   //[#]  /* {{{ */
{
	QFile file;
	file.setFileName(k_file_plu_spec);
	if (false == file.open(QIODevice::ReadOnly)) {
		LOG_E("<Plu List> Open PLU SPEC Failed");
		return -1;
	}

	QTextStream tmpStream(&file);
	QString     tmpLine;
	STFileInfo 	stList;
	QString    html, movie;
	m_tempPluList.clear();
	while (!tmpStream.atEnd())
	{
		tmpLine = tmpStream.readLine();
		stList.serial = tmpLine.section(':',0,0).trimmed().toInt();

		if (stList.serial == plu) {
			html   = tmpLine.section(':',1,1).trimmed();
			movie  = tmpLine.section(':',2,2).trimmed();
			stList.timeout= tmpLine.section(':',3,3).trimmed().toInt();

			if(0==stList.timeout) {
				if (0<m_xbootConf.getTimeout()) {
					stList.timeout = m_xbootConf.getTimeout();
				} else {
					stList.timeout = k_default_timeout;
				}
			}

			if(!html.isEmpty()) {
				stList.file = QString(k_html_path) + html;
				if (isFileExist(stList.file.toStdString().c_str())) {
					stList.type = EHtml;
					m_tempPluList.push_back(stList);
				} 
			}

			if(!movie.isEmpty()) {
				stList.file = QString(k_movie_path) + movie;
				if (isFileExist(stList.file.toStdString().c_str())) {
					if (isPicture(movie.toStdString().c_str())) {
						stList.type = EPicture;
					} else {
						stList.type = EVideo;
					}
					m_tempPluList.push_back(stList);
				} 
			}
		}
	}
	if (m_tempPluList.size() == 0) {
		LOG_E("Error.Plu.list.Empty");
		return -1;
	}
	file.close();
	return 0;
} /* }}} */

void XInfomatLayoutManager::setScreenMode(const int ScreenMode)   // [#]  /* {{{ */
{
	switch (ScreenMode)
	{
	case EPartialScreen:   //do partial screen
		setPlayersGeometryWithLayout();
		break;
	case EFullScreen:      //do full screen
		m_xHtmlPlayer->setPlayerGeometry(0,0,800,600);
		m_xMoviePlayer->setPlayerGeometry(0,0,800,600);
		break;
	default:
		LOG_E("<setScreenMode> No such Command");
		break;
	}
}/* }}} */

void XInfomatLayoutManager::setPlayersGeometryWithLayout()   // [#]  /* {{{ */
{
	switch (m_layout)
	{  //not handle with LAYOUT1
	case k_layout_2:  //WM1+VIDEO
	case k_layout_4:  //WM1+HTML
	case k_layout_8:  //WM2+VIDEO
	case k_layout_9:  //WM2+HTML
		m_xHtmlPlayer->setPlayerGeometry(0,165,800,435);
		m_xMoviePlayer->setPlayerGeometry(0,165,800,435);
		break;
	case k_layout_3:  //Video
	case k_layout_5:  //Html
		m_xHtmlPlayer->setPlayerGeometry(0,0,800,600);
		m_xMoviePlayer->setPlayerGeometry(0,0,800,600);
		break;
	case k_layout_6:  //QueueHead + Video/Html
		m_xHtmlPlayer->setPlayerGeometry(0,120,800,480);
		m_xMoviePlayer->setPlayerGeometry(0,120,800,480);
		break;

	default:
		m_xMoviePlayer->setPlayerGeometry(0,165,800,435);
		m_xHtmlPlayer->setPlayerGeometry(0,165,800,435);
		break;
	}
	return;
} /* }}} */

int  XInfomatLayoutManager::updatePlayList ()    /*  [#] */ /* {{{ */
{
	QDateTime playListLastModified = QFileInfo(QString(k_file_playlist)).lastModified();
	if (playListLastModified == m_playListLastModified) {
//		LOG_T("[No Change]Playlist");
		return 0;
	}
	LOG_T("[Changed] New playlist");
	m_playListLastModified = playListLastModified;	
	buildRoutineList();
	return 0;
} /* }}} */

int XInfomatLayoutManager::buildRoutineList()   /* [#] */ /* {{{ */
{
	QFile file;
	file.setFileName(k_file_playlist);
	if (false == file.open(QIODevice::ReadOnly)) { 
		LOG_E("<Routine List> Open File Failed");
		return -1;
	}

	QTextStream tmpStream(&file);
	QString     tmpLine;
	STFileInfo 	stList;
	QString     html, movie;
	m_playlist.clear();
	while (!tmpStream.atEnd())
	{
		tmpLine = tmpStream.readLine();
		stList.serial = tmpLine.section(':',0,0).trimmed().toInt();
		html   = tmpLine.section(':',1,1).trimmed();
		movie  = tmpLine.section(':',2,2).trimmed();
		stList.timeout= tmpLine.section(':',3,3).trimmed().toInt();
		if(0==stList.timeout) {
			if (0<m_xbootConf.getTimeout()) {
				stList.timeout = m_xbootConf.getTimeout();
			} else {
				stList.timeout = k_default_timeout;
			}
		}
		if(!html.isEmpty()) {
			stList.file = QString(k_html_path) + html;
			if (isFileExist(stList.file.toStdString().c_str())) {
				stList.type = EHtml;
				m_playlist.push_back(stList);
			}
		}
		if(!movie.isEmpty()) {
			stList.file = QString(k_movie_path) + movie;
			if (isFileExist(stList.file.toStdString().c_str())) {
				if (isPicture(movie.toStdString().c_str())) {
					stList.type = EPicture;
				} else {
					stList.type = EVideo;
				}
				m_playlist.push_back(stList);
			}
		}
	}
	if (m_playlist.size() ==0) {
		stList.type = EHtml;
		stList.timeout = 5000;
		stList.serial = 0;
		stList.file = "/usr/infomat/teraoka.htm";
		m_playlist.push_back(stList);
		LOG_T("Warning:Playlist Empty.Set Default Html");
	}
	file.close();
	return 0;
} /*  }}} */

/* ===========================================================================
 * =================   SIGNAL - SLOT =========================================
 * ==========================================================================*/
void XInfomatLayoutManager::onQueueDown()    // [-slot] /* {{{ */
{
	bool needSwitchPartial = true;
	doRoutine(needSwitchPartial);
	m_isPlayingPlu = false;
} /* }}} */

void XInfomatLayoutManager::onCPlayerIdle() /* {{{ */
{ 
	// Connection with XMoviePlayer
	LOG_T("[Confirm][CPlayer][STOPPED]");
	disconnect (m_xMoviePlayer, SIGNAL(sgCPlayerIdle()), this, SLOT(onCPlayerIdle()));  
	m_isCPlayerIdle = true; //only here set to true
	m_xHtmlPlayer->hide();
} /* }}} */

void XInfomatLayoutManager::onCheckPlayers()  /* {{{ */
{
	if (m_isHtmlIdle) {
		if (m_isCPlayerIdle) {
			LOG_T("Html && CPlayer are Valid");
			m_tmCheckPlayers.stop();
			m_isPlayersValid = true;
			m_isHtmlIdle = false;    //reset
			m_isCPlayerIdle = false; //reset
			m_isPlayingPlu = false;
			if (m_isTempPassPluValid && m_isPassPluValid) {  // Hanle with massive PLU request
//				LOG_T("[EVENT SETTING][PLU] Current:[%02d], 0-R,1-Plu",m_event);
				m_event = EPlu;
			}
			processInfomatEvents();
		} // ELSE -> Keep Checking CPLAYER
	} 
} /* }}} */

/* ============================================================
 * 				 DEBUG USING 
 * ============================================================*/
void XInfomatLayoutManager::debugOutput()    //[#] /* {{{ */
{
	LOG_T("*******************************");
	LOG_T("Routine List: (playlist)");
	LOG_T("*******************************");
	for (m_playIndex=0; m_playIndex<m_playlist.size(); ++m_playIndex) {
			LOG_T("-------------%02d-------------", m_playIndex);
			LOG_T("serial:\t[%02d]", m_playlist[m_playIndex].serial);
			LOG_T("file:\t[%s]",m_playlist[m_playIndex].file.toStdString().c_str());
			LOG_T("timeout:\t[%02d]", m_playlist[m_playIndex].timeout);
			LOG_T("type:\t[%02d]", m_playlist[m_playIndex].type);
	}
	m_playIndex = 0;

	LOG_T("*******************************");
	LOG_T("PLU List (plu.spec):");
	LOG_T("*******************************");
	for (int i=0; i<m_plulist.size(); ++i) {
		LOG_T("-------------%02d-------------", i);
		LOG_T("serial:\t[%02d]", m_plulist[i].serial);
		LOG_T("file:\t[%s]",m_plulist[i].file.toStdString().c_str());
		LOG_T("timeout:\t[%02d]", m_plulist[i].timeout);
		LOG_T("type:\t[%02d]", m_plulist[i].type);
	}
	m_playIndex = 0;
} /* }}} */
